﻿using Emgu.CV;
using Emgu.CV.Structure;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static 仪表识别2.DrawTableControl;

namespace 仪表识别2
{
    public partial class Form1 : Form
    {
        public static Form1 form;
        private Log log;
        private TabManager tabManager;
        private Image<Bgr, byte> image;
        private MeterImageProcess imageProcess;

        private VideoCapture capture = null;
        Task task = null;
        public Form1()
        {
            InitializeComponent();
            form = this;
            CheckForIllegalCrossThreadCalls = false;
            //初始化日志组件
            Log.richTextBox = LogInfoBox;
            Log.leve = 1;
            //重绘tabconrtol
            //DrawTabControl dtc = new DrawTabControl(tabControl1, this.Font);
            //dtc.ClearPage();
            //tab操作
            tabManager = new TabManager(this.tabControl1);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            loadConfig();
        }
        private void Proccess(object sender, EventArgs e)
        {
            Image<Bgr, byte> image = new Image<Bgr, byte>(capture.Width, capture.Height);
            capture.Retrieve(image, 0);
            this.image = image;
            Images._image = image;
            Images.image = image;
            tabManager.addTabPageWithPicBox("原始图像", image.Bitmap);
            Util.delay(AppConstant.delay);
        }
        private void PlayVideo(string fileName)
        {
            try
            {
                capture = new VideoCapture(fileName);
                capture.ImageGrabbed += Proccess;
                capture.Start();
            }
            catch (Exception e)
            {
                //Console.WriteLine(e.Message+"\n"+e.StackTrace);
            }
        }
        private void PlayVideo(int index)
        {
            try
            {
                capture = new VideoCapture(index);
                capture.ImageGrabbed += Proccess;
                capture.Start();
            }
            catch (Exception e)
            {
                
            }
        }
        
        private void 打开视频ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog fileDialog = new OpenFileDialog();
            fileDialog.Filter = "视频文件(*.avi,*.mp4)|*.avi;*.mp4";
            DialogResult result = fileDialog.ShowDialog();
            if (result == DialogResult.OK)
            {
                AppConstant.isVedio = false;
                ImageParams.pointStart = Point.Empty;
                ImageParams.pointEnd = Point.Empty;
                AppConstant.isVedio = true;
                PlayVideo(fileDialog.FileName);
                if(task==null)
                {
                    task = new Task(process);
                }
                AppConstant.runState = 1;
            }

        }
        private void 打开摄像头ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AppConstant.isVedio = true;
            PlayVideo(0);
            task = new Task(process);
            AppConstant.runState = 1;
        }
        private void process()
        {

            ImageParams.pointStart = Point.Empty;
            ImageParams.pointEnd = Point.Empty;
            ImageParams.pointerStart = Point.Empty;
            ImageParams.pointerEnd = Point.Empty;
            MeterImageProcess meterImageProcess = new MeterImageProcess(Images.image);
            meterImageProcess.tabManager = tabManager;
            meterImageProcess.run();

            //CvInvoke.WaitKey(100);
            Util.delay(AppConstant.delay);
        }
        private void Open_Click(object sender, EventArgs e)
        {
            OpenFileDialog fileDialog = new OpenFileDialog();
            fileDialog.Filter = "图片文件(*.jpg,*.jpeg,*.png,*.bmp)|*.jpg;*.jpeg;*.png;*.bmp";
            DialogResult result = fileDialog.ShowDialog();
            if (result == DialogResult.OK)
            {
                AppConstant.isVedio = false;
                image = new Image<Bgr, byte>(new Bitmap(Image.FromFile(fileDialog.FileName)));
                Images._image = image;
                Images.image = image;
                tabManager.addTabPageWithPicBox("原始图像", image.Bitmap);
                ImageParams.pointStart = Point.Empty;
                ImageParams.pointEnd = Point.Empty;
                
            }
        }
        private void RunBtn_Click(object sender, EventArgs e)
        {
            if (!AppConstant.isVedio)
            {
                if (Images.image == null)
                {
                    Log.error("请先打开一张图片");
                    return;
                }

                MeterImageProcess meterImageProcess = new MeterImageProcess(Images.image);
                meterImageProcess.tabManager = tabManager;
                meterImageProcess.run();
                
            }
            else if (AppConstant.runState == 1 )
            {
                if (Images.image == null)
                {
                    Log.error("请先打开一张图片");
                    return;
                }

                MeterImageProcess meterImageProcess = new MeterImageProcess(Images.image);
                meterImageProcess.tabManager = tabManager;
                meterImageProcess.run();
                AppConstant.runState = 2;
                RunBtn.Text = "暂停";
            }
            else if (AppConstant.runState == 2)
            {
                capture.Stop();
                AppConstant.runState = 3;
                RunBtn.Text = "识别";
            }else if(AppConstant.runState == 3)
            {
                capture.Start();
                AppConstant.runState = 2;
                RunBtn.Text = "暂停";
            }

        }
   
        //放大镜菜单
        private void MannifyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.magnifierPicBox.Visible = true;
            AppConstant.showMannify = !AppConstant.showMannify;
            (sender as ToolStripMenuItem).Checked = !(sender as ToolStripMenuItem).Checked;
        }

        private void ColorDialogToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if((sender as ToolStripMenuItem).Checked)
            {
                ColorDialog colorDialog1 = new ColorDialog();
                colorDialog1.FullOpen = true; //是否显示ColorDialog有半部分
                                              //colorDialog1.CustomColors = colorDialog1.Color;//设置自定义颜色
                DialogResult result = colorDialog1.ShowDialog();
                if (result == DialogResult.OK)//确定事件响应
                {
                    Color color_from = colorDialog1.Color;
                    AppConstant.choseColor = color_from;
                }
            }
            (sender as ToolStripMenuItem).Checked = !(sender as ToolStripMenuItem).Checked;
        }

        private void ToGrayToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tabManager.addTabPageWithPicBox("灰度图", imageProcess.toGray(image).Bitmap);
        }

        private void ToBinToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Image<Gray, byte> gray = imageProcess.toGray(image);
            tabManager.addTabPageWithPicBox("二值图", imageProcess.toBin(gray, 100,255).Bitmap);
        }

        private void MarkBtn_Click(object sender, EventArgs e)
        {
            //AppConstant.markModel = true;
            //AppConstant.pointerMarkModel = false;
            //Form1.form.tipLable.ForeColor = Color.Red;
            //this.tipLable.Text = "现在依次标记刻度起始点和终点，可在\"工具\"菜单中打开放大镜";
        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {
            if (textBox2.Text != "")
            {
                ImageParams.range = Int32.Parse(textBox2.Text);
            }
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Modifiers == Keys.Control && e.KeyCode == Keys.Up)
            {
                ImageParams.zoom *= 2F;
                PictureBox pb = (PictureBox)Form1.form.tabControl1.TabPages[0].Controls[0];
                Image<Bgr, byte> image = Images._image.Copy();
                image = image.Resize(ImageParams.zoom, Emgu.CV.CvEnum.Inter.Area);
                image = image.Rotate(ImageParams.rotationAngle, new Bgr(Color.Black), true);
                Images.image = image;
                pb.Image = Images.image.Bitmap;
                Log.debug("放大图像("+ImageParams.zoom+"):宽 " + Images.image.Width + " 高 " + Images.image.Height);

            }
            if (e.Modifiers == Keys.Control && e.KeyCode == Keys.Down)
            {
                ImageParams.zoom *= 0.5F;
                PictureBox pb = (PictureBox)form.tabControl1.TabPages[0].Controls[0];
                Image<Bgr, byte> image = Images._image.Copy();
                image = image.Resize(ImageParams.zoom, Emgu.CV.CvEnum.Inter.Area);
                image = image.Rotate(ImageParams.rotationAngle, new Bgr(Color.Black), true);
                Images.image = image;

                pb.Image = Images.image.Bitmap;
                Log.debug("缩小图像(" + ImageParams.zoom + "):宽 " + Images.image.Width + " 高 " + Images.image.Height);

            }
            if (e.Modifiers == Keys.Control && e.KeyCode == Keys.Left)
            {
                ImageParams.rotationAngle += 10;
                PictureBox pb = (PictureBox)Form1.form.tabControl1.TabPages[0].Controls[0];
                Image<Bgr, byte> image = Images._image.Copy();
                image = image.Rotate(ImageParams.rotationAngle, new Bgr(Color.Black),true);
                image = image.Resize(ImageParams.zoom, Emgu.CV.CvEnum.Inter.Area);
                Images.image = image;

                pb.Image = Images.image.Bitmap;
                Log.debug("左旋转图像:角度 "+ImageParams.rotationAngle);
            }
            if (e.Modifiers == Keys.Control && e.KeyCode == Keys.Right)
            {
                ImageParams.rotationAngle -= 10;
                PictureBox pb = (PictureBox)Form1.form.tabControl1.TabPages[0].Controls[0];
                Image<Bgr, byte> image = Images._image.Copy();
                image = image.Rotate(ImageParams.rotationAngle, new Bgr(Color.Black), true);
                image = image.Resize(ImageParams.zoom, Emgu.CV.CvEnum.Inter.Area);
                Images.image = image;

                pb.Image = Images.image.Bitmap;
                Log.debug("右旋转图像:角度 " + ImageParams.rotationAngle);
            }
        }

        private void PointMarkBtn_Click(object sender, EventArgs e)
        {
           
        }

        private void 初始化表盘ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AppConstant.testClockDial = true;
            ImageParams.circlesWithSomeFrame.Clear();
        }

        private void SingleCheck1(object sender)   //自定义函数  
        {
            自动检测ToolStripMenuItem.Checked = false;
            手动定位ToolStripMenuItem.Checked = false;
            ((ToolStripMenuItem)sender).Checked = true;
        }
        private void SingleCheck2(object sender)   //自定义函数  
        {
            rGSToolStripMenuItem.Checked = false;
            cTMToolStripMenuItem.Checked = false;
            houghToolStripMenuItem.Checked = false;
            ((ToolStripMenuItem)sender).Checked = true;
        }
        private void 自动检测ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SingleCheck1(sender);

        }

        private void 手动定位ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SingleCheck1(sender);
            AppConstant.markModel = true;
            AppConstant.pointerMarkModel = false;
            this.tipLable.Text = "现在依次标记刻度起始点和终点，可在\"工具\"菜单中打开放大镜";
        }

        private void rGSToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AppConstant.pointerLocationType = AppConstant.PointerLocationType.RGS;
            SingleCheck2(sender);
        }

        private void cTMToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AppConstant.pointerLocationType = AppConstant.PointerLocationType.CTM;
            AppConstant.markModel = false;
            AppConstant.pointerMarkModel = true;
            AppConstant.markTimes = 0;
            ImageParams.templateGray = null;
            ImageParams.pointerStart = Point.Empty;
            ImageParams.pointerEnd = Point.Empty;
            this.tipLable.Text = "现在依次标记指针起始点(近圆心端)和终点(远圆心端)，可在\"工具\"菜单中打开放大镜";
            SingleCheck2(sender);
        }

        private void houghToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AppConstant.pointerLocationType = AppConstant.PointerLocationType.Hough;

            SingleCheck2(sender);
        }

        private void 载入配置ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            loadConfig();
        }
        private void loadConfig()
        {
            PropertyUtil p = new PropertyUtil("config.properties");
            ImageParams.binThreshold = int.Parse(p["bin_threshold"].ToString());
            ImageParams.circle_min_r = int.Parse(p["circle_min_r"].ToString());
            ImageParams.circle_max_r = int.Parse(p["circle_max_r"].ToString());
            ImageParams.dilate = int.Parse(p["dilate"].ToString());
            ImageParams.erode = int.Parse(p["erode"].ToString());
            ImageParams.rscd_min_contours_len = int.Parse(p["rscd_min_contours_len"].ToString());
            ImageParams.rscd_area_radius = int.Parse(p["rscd_area_radius"].ToString());
            ImageParams.rscd_max_point_in_area = int.Parse(p["rscd_max_point_in_area"].ToString());
        }




        private void GrayImageStripMenuItem_Click(object sender, EventArgs e)
        {
            ImageShowStatus.showGray = !ImageShowStatus.showGray;
        }

        private void FilterImageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ImageShowStatus.showFilter = !ImageShowStatus.showFilter;
        }

        private void BinImageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ImageShowStatus.showBin = !ImageShowStatus.showBin;
        }

        private void CannyImageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ImageShowStatus.showCanny = !ImageShowStatus.showCanny;
        }

        private void ContourImageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ImageShowStatus.showContour = !ImageShowStatus.showContour;
        }

        private void CircleImageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ImageShowStatus.showCircle = !ImageShowStatus.showCircle;
        }

        private void LineImageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ImageShowStatus.showLine = !ImageShowStatus.showLine;
        }

        private void ScaleContourImageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ImageShowStatus.showScaleContour = !ImageShowStatus.showScaleContour;
        }

        private void ScaleFittingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ImageShowStatus.showScaleFitting = !ImageShowStatus.showScaleFitting;

        }

        private void 圆形单指针ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ImageParams.meterType = ImageParams.MeterType.CIRCLE;
        }

        private void 非圆形单指针ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ImageParams.meterType = ImageParams.MeterType.NOT_CIRCLE;
        }

        private void 区域选择ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            
        }
    }
}
